package com.javasee.aiqueue;

import com.javasee.common.module.ModuleEnableConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.locks.ReentrantLock;
/**
 * data数据文件管理
 * @author : xinyanfei
 * @date : 2025-08-27 15:53:01
 * Copyright (c) , 京东商城  All Rights Reserved.
 */
@Service
@Profile(ModuleEnableConst.AIQUEUE)
public class AiDataFileService {

    @Autowired
    AiQueueProperties aiQueueProperties;
    @Autowired
    AiIndexFileService aiIndexFileService;

    private final ReentrantLock fileLock = new ReentrantLock();
    private final AiIndexFileService indexManager;

    private MappedByteBuffer writeDataMappedByteBuffer;
    private MappedByteBuffer readDataMappedByteBuffer;


    @Autowired
    public AiDataFileService(AiIndexFileService indexManager) {
        this.indexManager = indexManager;
    }

    @PostConstruct
    public void init() throws IOException {
        System.out.println("===================初始化data.dat文件 开始===================");
        String data = aiQueueProperties.getFileHome() + File.separator + aiQueueProperties.getData();
        File file = new File(data);
        file.getParentFile().mkdirs();
        if (!file.exists()) {
            file.createNewFile();
        }

        RandomAccessFile dataFile = null;
        RandomAccessFile raf  = null;

        try {
            dataFile = new RandomAccessFile(file, "rwd");

            this.writeDataMappedByteBuffer = dataFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, aiIndexFileService.maxPerFile);

            raf = new RandomAccessFile(file, "r");
            this.readDataMappedByteBuffer = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, aiIndexFileService.maxPerFile);
            this.writeDataMappedByteBuffer.order(ByteOrder.BIG_ENDIAN);
            this.readDataMappedByteBuffer.order(ByteOrder.BIG_ENDIAN);

            if (aiIndexFileService.writeOffset>0){
                this.writeDataMappedByteBuffer.position(aiIndexFileService.writeOffset);
            }
            if (aiIndexFileService.readOffset>0){
                this.readDataMappedByteBuffer.position(aiIndexFileService.readOffset);
            }
        }catch (Exception e){
            aiIndexFileService.free(writeDataMappedByteBuffer);
            aiIndexFileService.free(readDataMappedByteBuffer);
            throw e;
        }finally {
            if (raf != null) {
                raf.close();
            }
            if (dataFile != null) {
                dataFile.close();
            }
        }
        System.out.println("===================初始化data.dat文件 结束===================");
    }

    /**
     * 写数据： 数据长度 + 数据内容
     *
     * @param data
     * @return
     * @throws IOException
     */
    public WriteResult writeData(byte[] data) throws IOException {
        fileLock.lock();
        try {
            //数据长度
            writeDataMappedByteBuffer.putInt(data.length);
            //数据内容
            writeDataMappedByteBuffer.put(data);
            // 更新写索引的偏移量
            int offset = 4 + data.length;
            aiIndexFileService.incrementWriteOffset(offset);

            // need sync
            this.sync();
            aiIndexFileService.sync();

            return new WriteResult(1, offset, data.length);
        } finally {
            fileLock.unlock();
        }
    }


    void sync() {
        writeDataMappedByteBuffer.force();
    }

    public static class WriteResult {
        private final int writeCount;
        private final long offset;
        private final int length;

        public WriteResult(int writeCount, long offset, int length) {
            this.writeCount = writeCount;
            this.offset = offset;
            this.length = length;
        }

        public int getWriteCount() {
            return writeCount;
        }

        public long getOffset() {
            return offset;
        }

        public int getLength() {
            return length;
        }
    }

    public byte[] readData(AiIndexFileService.AiQueueIndex index){
//        this.readDataMappedByteBuffer.position(index.offset);
//        //首次数据文件位空
//        if(readDataMappedByteBuffer.capacity()==0) return null;
//        //已读到最后
//        if(readDataMappedByteBuffer.position()==readDataMappedByteBuffer.capacity()) {
//            this.readDataMappedByteBuffer.load();
//            return null;
//        }

        if(this.readDataMappedByteBuffer.position() != index.offset){
            this.readDataMappedByteBuffer.position(index.offset);
            System.out.println("重置readDataMappedByteBuffer读取的index.offset = " + index.offset);
        }
        int length = this.readDataMappedByteBuffer.getInt();
        byte[] data = new byte[length];
        this.readDataMappedByteBuffer.get(data);

//        ByteArrayUtil
        if(data!=null && data.length>0){
            //更新offset
            this.aiIndexFileService.readOffset+=4+length;
        }
        return data;
    }
}